package bll

import (
	"context"
	"gitlab.local/backend/proto/dto"
	"manager/lib/trace_log"
	"manager/model"
	SignalPo "manager/model/signal"
	"manager/store/redis"
	"manager/utils"
	"manager/utils/goroutine_pool"
	"time"
)

var LoseLock = &loseLock{}

// loseLock 失联锁车功能
type loseLock struct {
}

// AddLoseLock 添加失窃锁
func (l *loseLock) AddLoseLock(sn string) (err error) {
	// 向redis中添加失窃锁车
	err = redis.KV.AddValueWithExpireTime(context.Background(), "lose_lock", sn, 1, time.Hour*24*90)
	if err != nil {
		trace_log.DebugLogger(sn, "AddLoseLock", "添加失窃锁车失败 err:", err)
	}

	// 锁车
	goroutine_pool.GetPool().Push(nil, func(data interface{}) error {
		l.DoLock(sn)
		return nil
	})

	trace_log.DebugLogger(sn, "AddLoseLock", "添加失窃锁车成功")
	return err
}

// RemoveLoseLock 移除失窃锁
func (l *loseLock) RemoveLoseLock(sn string) (err error) {
	bikeInfo, err := CacheBike.GetBikeInfoBySn(sn)
	if err != nil {
		return
	}
	flag := 0

	// 查找车辆信息
	recode, err := Lose.Find(context.Background(), &model.LoseInfoRequest{
		EbikeId: &bikeInfo.ID,
		Status:  &flag,
	})
	if err != nil || recode.Id <= 0 {
		return
	}

	redis.KV.DelValue(context.Background(), "lose_lock", sn)

	// 移除失窃
	err = l.UpdateStatus(sn, 1)
	if err != nil {
		trace_log.DebugLogger(sn, "RemoveLoseLock", "更新失窃锁车状态失败 err:", err)
		return
	}

	trace_log.DebugLogger(sn, "RemoveLoseLock", "删除失窃锁车成功")
	return
}

// DoLock 执行锁车功能
func (l *loseLock) DoLock(sn string) (err error) {
	defer utils.ExceptionCatch()
	if !redis.KV.ValueExist(context.Background(), "lose_lock", sn) {
		return
	}

	bikeInfo, err := CacheBike.GetBikeInfoBySn(sn)
	if err != nil {
		return
	}

	// 上报失窃进行锁车
	err = Signal.SendCmdToDevice(context.Background(), &SignalPo.CommandReq{
		EbikeId: bikeInfo.ID,
		Cmd:     int(dto.CmdType_CmdLock),
	})

	if err != nil {
		return
	}

	redis.KV.DelValue(context.Background(), "lose_lock", sn)

	// 更新锁车状态
	err = l.UpdateLockStatus(sn, 1)
	if err != nil {
		trace_log.DebugLogger(sn, "DoLock", "更新锁车状态失败 err:", err)
	} else {
		trace_log.DebugLogger(sn, "DoLock", "锁车成功")
	}
	return
}

// UpdateLockStatus 更新锁车状态
func (l *loseLock) UpdateLockStatus(sn string, lockStatus int) (err error) {
	bikeInfo, err := CacheBike.GetBikeInfoBySn(sn)
	if err != nil {
		return
	}
	flag := 0

	// 查找车辆信息
	recode, err := Lose.Find(context.Background(), &model.LoseInfoRequest{
		EbikeId: &bikeInfo.ID,
		Status:  &flag,
	})
	if err != nil || recode.Id <= 0 {
		trace_log.DebugLogger(sn, "UpdateLockStatus", "查找车辆信息失败 err:", err)
		return
	}

	// 更新锁车状态
	err = Lose.Update(context.Background(), &model.LoseUpdateRequest{
		Id:         recode.Id,
		LockStatus: &lockStatus,
	})
	return
}

// UpdateStatus 更新状态
func (l *loseLock) UpdateStatus(sn string, status int) (err error) {
	bikeInfo, err := CacheBike.GetBikeInfoBySn(sn)
	if err != nil {
		return
	}
	flag := 0

	// 查找车辆信息
	recode, err := Lose.Find(context.Background(), &model.LoseInfoRequest{
		EbikeId: &bikeInfo.ID,
		Status:  &flag,
	})
	if err != nil || recode.Id <= 0 {
		return
	}

	// 更新锁车状态
	err = Lose.Update(context.Background(), &model.LoseUpdateRequest{
		Id:     recode.Id,
		Status: &status,
	})
	return
}
